from app import app
from flask import  render_template
# from flask import  request

@app.route('/')
@app.route('/index')
def index():
    return "Hello,world"


@app.route('/hello')
def hello():
    return "hello world"

@app.route('/user/<username>')
def show_user_profile(username):
    return 'User %s' % username

@app.route('/post/<int:post_id>')
def show_post(post_id):
    return 'Post %d' % post_id

@app.route('/projects/')
def projects():
    return 'The project page'

@app.route('/about')
def about():
    return 'The about page'
'''
test_request_context()
即使我们正在通过 Python 的 shell 进行交互，它依然会告诉 Flask 要表现为正在处理一个请求。请看下面的解释
为什么你要构建 URL 而非在模板中硬编码？这里有三个绝妙的理由：

反向构建通常比硬编码的描述性更好。更重要的是，它允许你一次性修改 URL， 而不是到处边找边改。
URL 构建会转义特殊字符和 Unicode 数据，免去你很多麻烦。
如果你的应用不位于 URL 的根路径（比如，在 /myapplication 下，而不是 / ）， url_for() 会妥善处理这个问题。

'''

'''
HTTP （与 Web 应用会话的协议）有许多不同的访问 URL 方法。默认情况下，路由只回应 GET 请求，
但是通过 route() 装饰器传递 methods 参数可以改变这个行为。这里有一些例子:
'''
@app.route('/login',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        print("do_the_login()")
    else:
        print("show_the_login_form()")

'''
在模板里，你也可以访问 request 、 session 和 g [1] 对象， 以及 get_flashed_messages() 函数。

模板继承让模板用起来相当顺手。如欲了解继承的工作机理，请跳转到 模板继承 模式的文档。
最起码，模板继承能使特定元素 比如页眉、导航栏和页脚）可以出现在所有的页面。

自动转义功能默认是开启的，所以如果 name 包含 HTML ，它将会被自动转义。
如果你能信任一个变量，并且你知道它是安全的（例如一个模块把 Wiki 标记转换为 HTML），
你可以用 Markup 类或 |safe 过滤器在模板中把它标记为安全的。在 Jinja 2 文档中，你会看到更多的例子。
'''

@app.route('/nihao/')
@app.route('/nihao/<name>')
def nihao(name=None):
    return render_template('hello.html',name=name)

'''
文件上传
用 Flask 处理文件上传很简单。只要确保你没忘记在 HTML 表单中设置 enctype="multipart/form-data" 属性，
不然你的浏览器根本不会发送文件。

已上传的文件存储在内存或是文件系统中一个临时的位置。你可以通过请求对象的 files 属性访问它们。
每个上传的文件都会存储在这个字典里。它表现近乎为一个标准的 Python file 对象，但它还有一个 save() 方法，
这个方法允许你把文件保存到服务器的文件系统上。这里是一个用它保存文件的例子:


如果你想知道上传前文件在客户端的文件名是什么，你可以访问 filename 属性。但请记住
 永远不要信任这个值
，这个值是可以伪造的。如果你要把文件按客户端提供的文件名存储在服务器上，
那么请把它传递给 Werkzeug 提供的 secure_filename() 函数:

'''
from flask import  request

from werkzeug import  secure_filename

@app.route('/upload',methods=['GET','POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['the_file']
        f.save('/var/www/uploads/' + secure_filename(f.filename))

'''
Cookies
你可以通过 cookies 属性来访问 Cookies，用响应对象的 set_cookie 方法来设置 Cookies。
请求对象的 cookies 属性是一个内容为客户端提交的所有 Cookies 的字典。
如果你想使用会话，请不要直接使用 Cookies，请参考 会话 一节。
在 Flask 中，已经注意处理了一些 Cookies 安全细节。

读取 cookies:



'''
@app.route('/c')
def indexc():
    username = request.cookies.get('username')
    return username
from flask import  make_response

'''
可注意到的是，Cookies 是设置在响应对象上的。
由于通常视图函数只是返回字符串，之后 Flask 将字符串转换为响应对象。如果你要显式地转换，
你可以使用 make_response() 函数然后再进行修改。



'''

@app.route('/cs')
def indexcs():
    resp = make_response(render_template('hello.html'))
    resp.set_cookie('username','the username','xxx','yyy','ccc')
    return  resp
'''
重定向和错误
你可以用 redirect() 函数把用户重定向到其它地方。放弃请求并返回错误代码，用 abort() 函数。
这里是一个它们如何使用的例子:
'''

from flask import  abort,redirect,url_for,render_template
@app.route('/c1')
def c1():
    return redirect(url_for('login1'))

@app.route('/login1')
def login1():
    abort(404)
    print("这是一个空的执行")

# @app.errorhandler(404)
# def page_not_found(error):
#     return render_template('page_not_found.html'),404

@app.errorhandler(404)
def not_found(error):
    resp = make_response(render_template('page_not_found.html'),404)
    resp.headers['X-Something'] = 'A value'
    return resp



'''
视图函数的返回值会被自动转换为一个响应对象。如果返回值是一个字符串，
 它被转换为该字符串为主体的、状态码为 200 OK``的 、 MIME 类型是 ``text/html 的响应对象。
 Flask 把返回值转换为响应对象的逻辑是这样：

如果返回的是一个合法的响应对象，它会从视图直接返回。
如果返回的是一个字符串，响应对象会用字符串数据和默认参数创建。
如果返回的是一个元组，且元组中的元素可以提供额外的信息。
这样的元组必须是 (response, status, headers) 的形式，且至少包含一个元素。
 status 值会覆盖状态代码， headers 可以是一个列表或字典，作为额外的消息标头值。
如果上述条件均不满足， Flask 会假设返回值是一个合法的 WSGI 应用程序，并转换为一个请求对象。
如果你想在视图里操纵上述步骤结果的响应对象，可以使用 make_response() 函数。

'''
@app.errorhandler(401)
def not_visit(error):
    return render_template('visit.html'),401

#这里提到的 escape() 可以在你模板引擎外做转义（如同本例）
from flask import  Flask,session,redirect,url_for,escape,request
@app.route('/api/')
def apiindex():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/api/login',methods=['GET','POST'])
def apilogin():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('apiindex'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''
@app.route('/api/logout')
def apilogout():
    session.pop('username',None)
    return redirect(url_for('apiindex'))
import os
# set the secret key.  keep this really secret:
app.secret_key = os.urandom(24)

'''
使用基于 cookie 的会话需注意: Flask 会将你放进会话对象的值序列化至 Cookies。
如果你发现某些值在请求之间并没有持久存在，然而确实已经启用了 Cookies，但也没有得到明确的错误信息。
这时，请检查你的页面响应中的 Cookies 的大小，并与 Web 浏览器所支持的大小对比。

'''

